%Copyright: C.G. van der Laan, cgl@rc.service.rug.nl, 05941-1525
%Version November 1994
\input blue.fmt  %\tolerance500\hbadness=499\hfuzz=5pt
\title{BLUe's Index}
\subtitle{---The principle, and some more\footnote*
 {BLUe stands for Mr. BLUe---my innocent user and relative of
  Ben Lee User of the \TeX book fame.}}

\issue{MAPS 95.1}

\keywords{Compatible extension, education,
index, macro writing,
number ranges,
one-pass job, ordering table,
plain \TeX,
reusable software parts,
software engineering,
sort keys.
}

\abstract{The creation of a modest index within
a one-pass \TeX{} job is proposed. In general a proof run
and a final run are needed.}

\contents{Introduction
\quad The process and files involved
\quad Why?
\quad Disclaimer
\quad Notations and definitions
Example of use: From the \TeX book
Example of use: Accents and the like
Index Reminders
\quad Syntax
\quad Markup
\quad Examples of IR markup
\qquad Spaces
\quad Writing IRs
Sort and compress: \cs{sortindex}
\quad Storing in an array
\quad Sorting
\qquad Ordering
\qquad Ordering table
\qquad To be ignored tokens
\quad Reduction of entries
\quad Transformation index.srt$\rightarrow$index.elm
Typeset: \cs{pasteupindex}
\quad Running headlines
Customization
\quad Adding tokens to be ignored
\quad Modifying ordering
\quad Enriching the index
\quad Typesetting the enriched file
Tests
Robustness
Availability, and what is needed from manmac
Looking backward
Looking forward
\quad Subsidiary entries
\quad Sorting keys
Acknowledgements, Conclusion, References
Appendix A: Data: IRs from \TeX book chapter 1-6
Appendix B: Index
Appendix C: The index macros.
}

\thisreferences{\TB{} and \LaTeX{} user's guide
are omni-present and not explicitly listed.}
\references{\chenp\dolwc
 \laancgh\laancgm\laancgv\makeindex\salomonda\salomondg}

%\loadallpictures
%\pictures{\indmodelpic}
\catcode`\^=7
{\catcode`\^=7 \obeylines
 \gdef\verbatimgobble#1^^M{}}
\beginscript
\head{Introduction}
Making an index is an art.
The fundamental problem is
\beginquote  What to include in the index?
\endquote
\noindent Computer-assisted indexing is not simple either.
Issues are
\bitem the markup of keywords or phrases
\bitem to associate page numbers
\bitem to sort and compress raw Index Reminders (IRs), and
\bitem to typeset the result.
\smallbreak\noindent
The latter opens the Pandorra box of markup and layout,
which prompts for a two-pass job.

Up till now  the sorting is
done outside of \TeX.\ftn{The index for the
   \TeX book was done by a multi-pass job. In proofmode the raw IRs
   are written to the file index, and in the final run the enriched file
   of index entries is encluded in the script, preceded by special
   markup definitions.}
However, producing a modest index in a one-pass
\TeX{} job is possible.
In `Sorting in BLUe,'
I already touched upon the issue of sorting IRs.

\noindent I'll build upon manmac's
\bitem syntax and types of Index Reminders (IRs)
\bitem writing to a file
\bitem associating page numbers, and
\bitem the formatting in two-columns.

\subhead{The process and files involved.}
Manmac stores the raw IRs in the file index.
I read the file index\ftn{Default index is the value of
  the toks variable \cs{irfile}, which is used in \cs{sortindex}.}
into an array for internal sorting.
After sorting I reduce the entries\ftn{Those which differ by page
   number are collected into one entry.}
and write the result to the file index.srt.
Then, I transform index.srt into the file
index.elm.\ftn{ Default index.elm is the value of the toks variable
      \cs{indexfile}, which is used in \cs{pasteupindex}.
      The transformation abandons the IR syntax.
      The part which specifies the kind of IR
      is deleted and the word part marked up
      accordingly.}
The result is typeset via \cs{pasteupindex}.

\subhead{Schematically} it comes down to
\bigskip
$$\vcenter{%\indmodelpic
\unitlength=6ex
 \xdim{7.5}\ydim{4}
\beginpicture
\put(2,0){\makebox(0,0){Result}}
\put(2,1){\vector(0,-1){.8}}
\put(2,1.25){\makebox(0,0){\cs{pasteupindex}}}
\put(5.5,1.6){\vector(-1,0){3}}
\put(2,3){\vector(0,-1){1.5}}
\put(2,3.25){\makebox(0,0){\cs{sortindex}}}
\put(2.5,2.9){\line(1,0){3}}
\put(5.5, 2.9){\vector(0,-1){.5}}
\put(5.5, 2.25){\makebox(0,0){`Enrich' index.elm\ }}
\put(5.5, 2){\line(0,-1){.4}}
\put(2,4.3){\vector(0,-1){.8}}
\put(2,4.5){\makebox(0,0){Copy + IR markup}}
\endpicture
}$$

\subhead{Why?}
For a professional index I agree with Knuth that one
can better sort and otherwise enrich the index outside
of \TeX. This obeys the separation of concerns principle.
However, there is nothing against it to provide
macros for producing modest indexes completely within \TeX.
Objections\ftn{If any :-).} will faint away hopefully,
because of the possibility
to {\it enrich the sorted and compressed
index (file) outside of \TeX.}
The latter is a step beyond manmac.
There the raw IRs are written to the file index,
while here the sorted and compressed IRs
can be worked upon.
My work is a compatible extension of manmac,
meaning that one can also start from the raw IRs,
if one wishes.

A side-effect is that the power of \TeX{} for practical
problems is demonstrated.

\subhead{Disclaimer.}
The macros are not foolproof.
Don't use as part of the IR
\bitem \TeX's special symbols
\bitem symbols with special catcodes, for example active symbols like
       the circumflex \char94,
       or the tilde \char126
\bitem as part of the IR a control sequence which is not accounted for.\ftn{In
the section
          Looking forward I'll explain how a user can allow for
          control sequences as part of the IR markup.}
\smallbreak

\subhead{Notations and definitions.}
manmac.tex stands for the macros used by Knuth for formatting
his Computers and Typesetting series of books, especially the \TeX book
and the \MF{} book.
Index reminders denote the markup of script words, to be included
in the index.
IRs is an abbreviation for Index Reminders.
\cs{ea}, \cs{nx} denote \cs{expandafter} and \cs{noexpand}.
OTR stands for output routine.
FIFO stands for First In First Out, as described in `FIFO and LIFO sing the
BLUes.' SiB denotes my `Sorting in BLUe' work.

\head{Example of use: From the \TeX book}
Let us take for this example some IRs from the first chapter
of the \TeX book. I took only part of it and introduced
\cs{newpage} now and then to enforce pages with zero, one or more
IRs. I used blue.fmt (with manmac embedded).
\thisverbatim{\catcode`\|=12 }
\beginverbatim
%Text from first chapter TeX book
Hence the name \TeX, which is an
uppercase form of $\tau\epsilon\chi$.
^^{TeX, meaning of}%modified
^^|\tau|^^|\epsilon|^^|\chi|
\newpage%no IRs next
Insiders pronounce the $\chi$ of \TeX\ as
a  Greek chi, not as an `x', so that
\TeX\ rhymes with the word blecchhh.
\newpage%three IRs next
In fact, ^{TEX} (pronounced {\sl tecks\/})
is the admirable {\sl Text EXecutive\/}
processor developed by^{Honeywell HIS}.
Since these two system names are
^^{Bemer, Robert}
pronounced quite differently, they should
also be spelled differently.
\newpage%one IR next
The correct way to refer to \TeX\ in a
computer file, or when using some other medium
that doesn't allow lowering of the `E',
is to type `^|TeX|'. Then there will be no
confusion with similar names, and people will
be primed to pronounce everything properly.
\sortindex
\pasteupindex
\bye
!endverbatim
\noindent which yields as  raw IRs (in file index)
\thisverbatim{\catcode`\*=0
   \catcode`\!=12 }
\beginverbatim
TeX, meaning of !0 1.
tau !2 1.
epsilon !2 1.
chi !2 1.
TEX !0 3.
Honeywell HIS !0 3.
Bemer, Robert !0 3.
TeX !1 4.
*endverbatim
\noindent and as index (in file index.elm)
\bigbreak\noindent{\bf Index}
\medskip\noindent
\line{\vbox{\noindent\hsize.5\hsize
\noindent {Bemer, Robert}{} 3.

\noindent {\tt \char 92\hbox {chi}}{} 1.

\noindent {\tt \char 92\hbox {epsilon}}{} 1.

\noindent {Honeywell HIS}{} 3.
}\vbox{\noindent\hsize.5\hsize
\noindent {\tt \char 92\hbox {tau}}{} 1.

\noindent {TEX}{} 3.

\noindent {\tt TeX}{} 4.

\noindent {TeX, meaning of}{} 1.
}\hss}

\head{Example of use: Accents and the like}
I'll show how to mark up Knuth's four types of IRs
and how to mark up accents, font switching, and
spaces as part of the IR.
The last IR markup shows that the  representation of page numbers
as a range comes out automatically too.
\thisverbatim{\catcode`\|=12
   \catcode`!=12 \catcode`\*=0 }
\beginverbatim
Types of IR
 0  ^{return}
 1  ^|verbatim|
 2  ^|\controlsequence|
 3  ^\<syntactic quantity>

Accents in IR markup  ^{\'el\`eve!},
font changing in IR markup ^{\bf bold}
and spaces in IR markup ^{control\ symbol}

Control sequences ^{\TeX, and \AmSTeX}
^{Lamport and \LaTeX}

brackets ^{\tt< \rm and \tt>}
\newpage range representation ^{return}
\newpage                      ^{return}
\sortindex
\pasteupindex
\bye
*endverbatim
\noindent The above yields in file index as raw IRs
\thisverbatim{\catcode`\*=0
   \catcode`\!=12 }
\beginverbatim
return !0 1.
verbatim !1 1.
controlsequence !2 1.
syntactic quantity !3 1.
\'el\`eve! !0 1.
\bf{}bold !0 1.
control\ symbol !0 1.
\TeX, and \AmSTeX{} !0 1.
Lamport and \LaTeX{} !0 1.
\tt{}< \rm{}and \tt{}> !0 1.
return !0 2.
return !0 3.
*endverbatim
\noindent and in file index.elm as index
\bigbreak\noindent{\bf Index}
\medskip\noindent
\line{\vbox{\noindent\hsize.5\hsize
\noindent {\tt {}< \rm {}and \tt {}>}{} 1.

\noindent {\bf {}bold}{} 1.

\noindent {control\ symbol}{} 1.

\noindent {\tt \char 92\hbox {controlsequence}}{} 1.

\noindent {\'el\`eve!}{} 1.
}\vbox{\noindent\hsize.5\hsize
\noindent  {Lamport and \LaTeX{}} 1.

\noindent {\TeX, and \AmSTeX{}} 1.

\noindent {return}{} 1--3.

\noindent $\langle \hbox {syntactic
             quantity}\rangle ${} 1.

\noindent {\tt verbatim}{} 1.
}\hss}

\head{Index Reminders}
IRs are at the heart of the process. Knuth distinguished 4 types
to facilitate the outside processing.
I'll adopt his IRs syntax and types.
\subhead{Syntax.}
Knuth's IRs obey the syntax\ftn{In
  contrast with my previous given syntax it seems that Knuth was less
  restrictive. Earlier I overlooked that the entries are ended by
  a period.}
\thisverbatim{\emc}
\beginverbatim
<word(s)>!]!!<digit>!]<page number>.
!endverbatim
The digits  0, 1, 2, or 3 denote the types: words,
verbatim words, control sequence, and syntactic quantity.
A user does not have to bother about the digits, nor about the
page numbers.
Knuth has adopted the accompanying conventions for
the word(s) of IRs.\ftn{See \TB, p424 for the IR types, and what is typeset
   in the result. In \cs{vref} the markup is inserted as replacement
   text of \cs{next}. What is set in the index is governed by the macros which
    are included after \cs{begindoublecolumns} in the \TeX book script.}
$$\vbox{\offinterlineskip\def\tstrut{\vrule height2.5ex depth.5ex width0pt}
\halign{\tstrut#\hfill\quad\vrule\quad&#\hfill\quad\vrule\quad&#\hfill\cr
Mark up&Typeset in copy$^*$&IR \cr
\noalign{\hrule}
|^{...}|  &\dots        &|... !!0 |$\langle page\, no\rangle$.\cr
|^!vrt...!vrt|  &|!vrt...!vrt|&
                              |... !!1 |$\langle page\, no\rangle$.\cr
|^!vrt\...!vrt| &|!vrt\...!vrt| &
                               |... !!2 |$\langle page\, no\rangle$.\cr
|^\<...>|&$\langle\dots\rangle^{**}$&
                               |... !!3 |$\langle page\, no\rangle$.\cr
\noalign{\vskip.5ex\hrule width1cm\relax\vskip1ex}
\multispan3{\quad$^*\,$\vrt\dots\vrt\ denotes manmac's, TUGboat's,\dots
   verbatim.  \hfil}\cr
\multispan3{\quad$^{**}\,$in \cs{rm}. \hfil}\cr
}}$$
For the user the word(s) are important.
The allowed markup for the IRs and the result in the copy are
given in the accompanying table.

\subhead{Markup.} The markup for IRs is near to natural.
Precede the entry by a circumflex  (or  two circumflex(es) in case of
a silent index entry).\ftn{Silent IRs mean that these  will appear
   only in the index, not on the page.}


\example{IR markup.}
\thisverbatim{\catcode`\|=12 \catcode`\^=12
   \catcode`!=12 \catcode`*=0 }
\beginverbatim
^{text, e.g. \'el\`eve!}
^|verbatim text|
^|\controlsequence|
^\<a metalinguistic variable>
%and for silent ones, double the ^
^^\<a metalinguistic variable>
%from the TeX book
{\sl^{ligatures}}
|'$|^|\,||$''|
^^{markup commands, see control sequences}
%from Looking forward section
^{Lamport and \LaTeX}
*endverbatim

\subsubhead{Spaces} are as always difficult.
In the IR they separate parts of the IR, and are used
in the word part.

Just typing a space has as effect that
it will be neglected during  sorting.

The markup `\cs{\char32}', a control space,
will yield a space subject to sorting, according to
the ordering table.

\cs{space} markup will be neglected during sorting.
This token is default member of
the set of to be ignored control sequences.
It will be set in the index as \cs{\char32}.

\example{Spaces}
The following markup
\thisverbatim{\catcode`\|=12 }
\beginverbatim
Spaces test
^{\space}%an ignored cs
^{a\ a}  %control space
^{aa}
^{a\ b}
^{a \TeX}
^{a\ \bf a}
^{\TeX book}
^{xyz beta}%negelected in sorting
^{xyza}
^|\space|
\sortindex
\pasteupindex
\bye
!endverbatim
\noindent yields as file index
\thisverbatim{\catcode`\!=12
              \catcode`\;=0 }
\beginverbatim
\space {} !0 1.
a\ a{} !0 1.
aa{} !0 1.
a\ b{} !0 1.
a \TeX {} !0 1.
a\ \bf a{} !0 1.
\TeX book{} !0 1.
xyz beta{} !0 1.
xyza{} !0 1.
space{} !2 1.
;endverbatim
\noindent and as file index.srt
\thisverbatim{\catcode`\!=12
              \catcode`\;=0 }
\beginverbatim
\space {} !0 1.
a\ \bf a{} !0 1.
a\ a{} !0 1.
a\ b{} !0 1.
aa{} !0 1.
a \TeX {} !0 1.
space{} !2 1.
\TeX book{} !0 1.
xyza{} !0 1.
xyz beta{} !0 1.
;endverbatim
Explanation. \cs{space} belongs to the set of to be
ignored control sequences, ICSs for short.
This means that it is skipped with respect to sorting,
except when it occurs as the last token of the word part.
In that case they are ordered as a space,
that is according to the lowest value.
This explains the position of `\cs{space}.'

`\cs{TeX},' and `\cs{TeX} book,' are subject to the default sort keys.

`xyza' precedes `xyz beta,' because the space is silent.
When word ordering is preferred a \cs{\char32}, a control space,  must
be included.

\subhead{Writing the IRs in index.}
This comes with manmac.
The writing is done in two phases:
first while processing the script, and
second in the OTR where the page numbers are attached.
The (manmac) macro which does the first part of the
writing is
\thisverbatim{\catcode`\~=0
   \catcode`\!=12 }
\beginverbatim
\def\makexref{\ifproofmode
   \bgroup\def\ {\string\ }%
   \xdef\writeit{\write\inx{\text{}
    !\xreftype\space
    \nx\number\pageno.}}\writeit
   \egroup
   \else\ifhmode\kern0pt\fi\fi
   \ifsilent\ignorespaces\else\next\fi}
~endverbatim
I don't write in the margin.
In Appendix C the  full-BLUe
macro has been provided.
Font changing control sequences, accents and \cs{space}
are written as a `string' in the file index.
Actually, I introduced also the sorting on sorting keys.
Because of the different use of \cs{space}
I introduced \cs{spaceseparator}.


\head{Sort and compress: \cs{sortindex}}
The functionality of \cs{sortindex} is to transform the file of
raw index reminders---index---into the file with sorted and compressed
index entries---index.elm.

All we have to do is to
\bitem write the raw IRs in the array,
       and keep the upper bound of the array in \cs{n},
\bitem sort with the right comparison macro (\cs{cmpir}, and
        at the lower level for the word part \cs{nxtwindex}),
        next to the use of the ordering table \cs{otindex}
\bitem reduce the index entries by collecting the same entries which differ
       by page number
\bitem write the result to the file index.srt, and transform this into
       index.elm.
\smallbreak
\beginverbatim
\def\sortindex{%Nov 1994, cgl
%Purpose:
%To sort IR file.
%Input: default index is sorted
%      ( file specified in \irfile)
%Output: file index.elm.
\newpage\immediate\closeout\inx
\filetoarray{\the\irfile}
\immediate\write16{Sorting n=\the\n.
    Please wait, O(nlog n) process.}
\let\cmp\cmpir\let\nxtw\nxtwindex
\otindex\let\ \space
\sort
{\let\spaceseparator\space
 \setupnxtokens\def\ {\nx\ }%
 \immediate\write16{Range reduction.}
 \redrngtofile{index.srt}
 \immediate\write16{After reduction and
  writing to file index.srt; n=\the\n.}
 \immediate\write16{Transform
       index.srt-->index.elm.}
 \tawfiletofile{index.srt}{\the
                  \indexfile}}}
!endverbatim\noindent
with auxiliary
\beginverbatim
\def\setupnxtokens{%
 \def\process##1{\def##1{\nx##1}}%
  \ea\fifo\the\conseqs\ofif
 \def\process##1{\def##1{\string##1}}%
  \ea\fifo\the\consyms\ofif
}
!endverbatim\noindent
In Appendix C the full-BLUe version has been incorporated.

\subhead{Storing in an array.}
The storing of data from a file into an array has been
treated in SiB. A slightly modified version of the
macro reads
\beginverbatim
\def\filetoarray#1{%#1 is file name
 \immediate\openin\inxin=#1\relax
 \ifeof\inxin\immediate\write16{File #1 empty
   or non-existent.}%
 \fi \n\kzero\continuetrue
 \loop\ifeof\inxin\continuefalse\fi
 \ifcontinue\advance\n1 \immediate
 \read\inxin t\ea o\csname\the\n\endcsname
 \repeat\advance\n-1
 \immediate\closein\inxin}
!endverbatim

\subhead{Sorting.}
For sorting I make use of my macros as released in SiB.
Comparison needs a multiple key.
This means that at the outer level we have to
supply \cs{cmpir}\ftn{Mnemonics compare index reminder.} and at the lower level
 we
have to compare words, and digits.
The words are handled by \cs{nxtwindex} and the numbers
are compared via an \cs{ifnum}. The comparison macro for
IRs reads
\thisverbatim{\unmc}
\beginverbatim
\def\cmpir#1#2{%#1, #2 defs
%Result: \status= 0, 1, 2 if
%        \val{#1} =, >, < \val{#2}
\ea\ea\ea\decom\ea#1#2}
!endverbatim
The crucial macro for comparison of the word part of the IR reads
\beginverbatim
\def\nxtwindex#1#2{%
%Function:
%On input: #1 contains the `word'
%As result: #2 contains the value
%   of the first non-ignored token as given
%   in the ordering table.
%#1 contains the rest of the `word'
 \def\pop##1##2\pop{%
 \gdef#1{##2}\def\pophead{##1}}%head and tail
 \ea\pop#1\pop%split in head and tail
 \ignores\ea\ea\ea{\ea\the\ea\conseqs
                        \the\consyms}%
 \ea\loc\pophead{\the\ignores}%
 \iffound\ifx\empty#1 \chardef#2=0
         \else\nxtwindex#1#2\fi
 \else
 \ea\let\ea#2\csname ot\pophead\endcsname\fi
}
%with toks variables
\conseq{\c\space\bf\it\rm\tt\TeX\sub}
\consyms{\`\'\"\^\~}
!endverbatim
The idea is to process the `word' argument by argument.\ftn{Not token
   by token, beware!}
However, some tokens are not relevant for the ordering
and have to be ignored. This is done by collecting
all tokens to be ignored in the toks variable \cs{ignores},
and compare \cs{pophead} with this string.
The above can be extended to control sequences to be sorted on
separately provided sorting keys. See the Looking forward section.

For \cs{decom} and other low level macros related to
sorting within \TeX{} see `BLUe's Format,' or
`Sorting in BLUe.'

In Appendix C the full-BLUe versions have been incorporated.

\subsubhead{Ordering.}
A fundamental issue with indexes is the ordering.
The ASCII table is not suited because lowercase and uppercase
letters differ by 32. I decided to rank these as equal, more
precisely to assign the lowercase ASCII values to both. I prefer
from the following the left column above the right one
\beginverbatim
el                          el
El!`eve                       em
em                          El!`eve
!endverbatim
Moreover, accented letters are not part of ASCII. How should we
order for example e, \'e, \`e, \^e, \"e?
I decided to rank accented letters equal to those without an accent,
because I prefer from the following the left column above the right one
\beginverbatim
el                          el
!leavevmode!'el!`eve                       em
em                          !'el!`eve
!endverbatim
I know that non-letters precede letters but what about there relative
ordering? I decided to stay as close as possible to the ASCII ordering.

Then there is the problem of digits. In IRs they come as part of the
word(s) and as page numbers. For the latter I used the numerical ordering.
For the former I used the alphabetical ordering.\ftn{I could have applied
  a look ahead mechanism and use numerical ordering throughout.
  Maybe another time.}

Furthermore, a user can select
the so-called `word ordering,'\ftn{This means that spaces precedes
    all letters. A space as such is neglected in the ordering.}
by \cs{\char32}, \TeX nically a control space, as markup for a space.
Personally, I like from the following the first column  better than
the second
\beginverbatim
sea lion                    seal
seal                        sea lion
!endverbatim

\subsubhead{Ordering table.}
This ordering `table' is simpler than the one released
in SiB, because accents have been ignored.
Furthermore, I adhere mostly to the ASCII ordering,
as can be seen easily.
\thisverbatim{\catcode`\|=12 \catcode`\!=12
   \catcode`\~=0 }
\beginverbatim
\def\otindex{%Parameters: Ordering `table'
%Special cases
\ea\chardef\csname ot \endcsname=0
\ea\chardef\csname ot\space\endcsname=0
%{|}~char126 come in ASCII after lowercase
%^ is active character
%Bulk according to ASCII
\def\process##1{\ea\chardef
   \csname ot##1\endcsname=`##1 }
%lowercase letters
\fifo abcdefghijklmnopqrstuvwxyz\ofif
\chardef\otij=`y \chardef\otIJ=`y
%other characters}
\fifo!"##$&'()*+,-./0123456789:;<=>?@
      []_`\ofif
%assign lowercase values to uppercase letters
\def\process##1{\ea\chardef
  \csname ot##1\endcsname=\lccode`##1 }
\uppercase{\fifo
  abcdefghijklmnopqrstuvwxyz\ofif}
}
~endverbatim
Attention needs \TeX's specials, in particular
the escape character \cs{},
the circumflex \char94,
and the percent \%.

\subsubhead{To be ignored tokens.}
In practice I needed things like \cs{tt}
as part of the IR, which must be neglected while sorting.\ftn{The reason is
  that {\tt <, and >} are used and then printed wrongly.}
I decided to ignore those tokens while sorting and to include
the tokens in the final index.elm as such.

Another realistic approach is to add this kind of markup later in the file
index.elm.

\subhead{Reduction of entries.}
The functionality is that the IRs which differ by page number
are collected into one entry with the page numbers represented
efficiently, for example in ranges.
The macros from SiB have the functionality
\beginverbatim
\def\redrngtofile#1{%Reduction of \1...\n,
%with range representation of page numbers.
%The result is written to file #1.
...
}
%
\def\prcrng#1{%Prints the numbers so far if
%the new number differs more than 1 from the
%last. If the difference is 1 the range is
%extended.
...}
%
\def\strnrs{%Accumulates numbers in \nrsrng.
%either as a range or as such.
%\frst stands for first number
%and \lst for last number. If they equal the
%number is stored, if they differ by 1 both
%the numbers are stored separated by \sepn,
%and if they differ by more than 1
%\frst--\lst is stored.
...}
!endverbatim
For the first macro see Appendix C. The other two have been released
already as part of blue.fmt and are unaltered.

\subhead{Transformation index.srt$\rightarrow$index.elm.}
When we inspect the copy for the index in the \TeX book file
then we'll find that the entries of the enriched file don't obey
the syntax of the IRs.
The part with !$\langle digit\rangle$ has disappeared.
Pondering about this made me agree with Knuth, as usual.\ftn{I noticed
   furthermore, that some IRs did not make it into the final index.
   Apparently, given the other IRs, he decided to delete less relevant
   ones.}
It is no longer functional!
The file can better be considered as copy as such, to be processed in the
final run.
Because of this I transformed index.srt, the file of sorted and compressed
IRs, into the file index.elm,
with the coding !$\langle digit\rangle$ absorbed as markup in the word part.
\beginverbatim
\def\tawfiletofile#1#2{% #1 from file
 \continuetrue         % #2 to file
 \immediate\openin\inxin=#1\relax
 \immediate\openout\inx=#2\relax
 \loop\read\inxin to\IR
   \ifeof\inxin\continuefalse\fi
 \ifcontinue\trfandwrite\IR
 \repeat
 \immediate\closein\inxin
 \immediate\closeout\inx
}
%with auxiliaries
\newread\inxin\newwrite\inx\newtoks\indword
\def\splitintoks#1 !#2 #3.{\indword{#1}%
  \chardef\digit=#2\relax\def\pagenrs{#3}}
%
\def\trfandwrite#1{\ea\splitintoks#1%
 \immediate\write\inx{\nx\noindent
  \ifcase\digit{\the\indword}\or
   {\nx\tt\the\indword}\or
   {\nx\tt\char92\hbox{\the\indword}}\or
   $\nx\langle\hbox{\the\indword}\nx\rangle
    $\fi\spaceseparator\pagenrs.}}
!endverbatim

\subsubhead{Explanation.} In \cs{trfandwrite} I used the
toks variable for storing the word part, because when writing
it comes out handy that \cs{the} is a one-step expansion.
Note that \cs{trfandwrite} takes care of the markup
for \cs{pasteupindex}. The \cs{noindent} is inserted to
enforce horizontal mode, especially in presence of
accents at the beginning of the word.

In \cs{tawfiletofile} the test for the end of file looks
peculiar.\ftn{Remember
   that \TeX{} appends a \cs{par} to the input file.}

\head{Typeset: \cs{pasteupindex}}
In the \TeX book the typesetting of the enriched index entries is
treated on p261--264. Let us start from there and distill
our specifications.

The typesetting of main and subsidiary entries is discussed
given the file of index entries. This is intertwinned with
the page break mechanism
in relation to what should appear in the running headlines.

My specifications for typesetting the index are
\bitem represent the four IR types the same as in the \TeX book
\bitem set in two-columns, balanced, possibly preceded
       by one-column copy
\bitem set subsidiary entries analogous to the \TeX book
\bitem indent continuation lines by 2em
\bitem indent subsidiary entries by 1em
\bitem underline page numbers which represent the definition or
       the main source of information
\bitem represent a page number in italics when that page contains
       an instructive example of the concept in question.
\smallbreak\noindent
Essentially nothing new.
The challenge is how to implement this,
such that an index can be handled in a one-pass job.

In order not to make things too complex, I'll postpone the handling
of subsidiary entries until the Looking forward section.
Let us say that this is a feature for the `next release,' of blue.fmt.
The enrichements such as representation of
numbers in italics or underlined, which have all
to do with the wish to direct readers to the main source or
to instructive examples, are left to the manual editing of
the index.elm file.
The reason is---In agreement with Knuth?---that
this is difficult to foresee at the time when the IR markup is inserted
in the script.
Moreover, it complicates the sorting et cetera process.

In the mean time users can  edit
index.elm---read add markup---and provide the necessary macros
in for example \cs{preindex}. In short follow  Knuth.

The compressed and sorted aray of index entries is
set via the invocation \cs{pasteupindex}.\ftn{As
   modification for the pair \cs{begindoublecolumns}
   and \cs{enddoublecolumns},
   because the latter is too much intertwinned with manmac.
   For an explanation of the underlying macro the reader is referred
   to the \TeX book p416--417.}
The contents of \cs{preindex}
and \cs{postindex} are used appropriately.


\beginverbatim
\def\pasteupindex{%Nov 1994, cgl
%Purpose:
%To set index in (balanced) doublecolumn.
%The index is preceded by contents of
%\preindex and followed by contents of
%\postindex.
%Input: default index.elm is set
%       (file specified in \indexfile).
%Biased by manmac's \begindoublecolumns
 \newpage\begingroup
 \def\space{{\tt\char32 }}%
 \the\preindex\par
 \pageheight\vsize
 \pagewidth\pagewd%anachronism
 \parindent1em
 \output={\global\setbox\partialpage=
  \vbox{\unvbox255\bigskip}}%
 \eject
 \output={\bluedoublecolumnout}%
 \hsize=8.5cm \vsize=51cm%blue.fmt values
 \parskip0pt plus.8pt\relax
 \obeylines\everypar{%
    \hangindent2\parindent}%
 \let\par\endgraf
 \let\sub\endgraf
%
 \input\the\indexfile\relax
%
%endpasteupindex part biased by
%manmac's \enddoublecolumns
 \output={\balancecolumns}\eject
 \endgroup
 \pagegoal=\vsize\the\postindex
}
%auxiliaries adapted from manmac
\def\bluedoublecolumnout{%
%Biased by manmac's doublecolumnout
 \splittopskip=\topskip
 \splitmaxdepth=\maxdepth \dimen@=25cm
 \advance\dimen@ by-\ht\partialpage
 \setbox0=\vsplit255 to\dimen@
 \setbox2=\vsplit255 to\dimen@
 \blueonepageout\pagesofar
 \unvbox255 \penalty\outputpenalty}
%
\def\blueonepageout#1{%
%Biased by manmac's \onepageout
 \shipout\vbox{%
 \vbox to\baselineskip{\null
         \the\headline\vss}%
 \kern2ex
 \vbox to\pageheight{#1}%
 \kern1ex
 \the\footline
 }\advancepageno}
!endverbatim
The file name is parameterized in a token variable \cs{indexfile}.
Default is |\indexfile{index.elm}|.
A user can specify his own file via
\thisverbatim{\emc}
\beginverbatim
\indexfile{<user index file>}
!endverbatim

\subhead{Running headlines.}
The advanced mechanism of having the top entries
and bottom entries appropriately represented
in the headline has been treated In the \TeX book.

Looking at the indexes
of the \TeX book and the more recent Graphbase book,
I noticed that Knuth did not use it.
In Appendix D he states that the index is not
tall enough to justify the mark mechanism.
It is really advanced and subtle, and for those who
are interested, please peruse the \TeX book.

\head{Customization}
A user might want to interfere at the places
\bitem to include other tokens to be ignored while sorting\ftn{However,
    in the Looking forward section this has been generalized into
    the possibility to provide the control sequence with a sorting key.}
\bitem to supply an ordering of his own
\bitem to enrich the sorted and compressed file index.elm.
\smallbreak

\subhead{Adding tokens to be ignored.}
In general we don't know what control sequences
stand for.

What are reasonable requirements to impose upon the handling of
markup control sequences (cs for short)? In my opinion
\bitem the cs must be defined
\bitem \cs{makexref} writes the cs unexpanded
\bitem ordering? unknown, and therefore neglected\ftn{However, see the
   Looking forward section, ;-).}
\bitem \cs{setupnxtokens} guards that the cs-s are written, unexpanded,
       to index.srt and index.elm.
\smallbreak
As a consequence I decided to neglect the `in between'
control sequences while sorting.
For those who favour a one-pass job, I have provided the following,
although it is simpler to add those control sequences to index.elm.

The extension of the set of to be ignored tokens
can be done via
\beginverbatim
\add#1to#2
%for example adding to set of control
%sequences
\add\hfil to\conseqs
%or control symbols
\add\`to\consyms
%Adding to the set of sort key pairs
\add\hfil{hfil}to\srtkeypairs
!endverbatim
Each element  from \cs{conseqs}
is redefined such that the control sequence
token is written to the file with a space
appended.\ftn{\cs{noexpand} is used
  instead of \cs{string}.}


\subhead{Modifying ordering.}
The most general way is to `copy' the ordering table
for modification.\ftn{My \cs{fifo} is just a short cut, which also
   prevents typos in assigning the ASCII values. For \cs{fifo}, see
   my `FIFO and LIFO sing the BLUes.'}

\subsubhead{And what about a macro to add to the table?}
This can be done easily, and superficially looks convenient
for an innocent user.
At the moment I don't trust the macros to be worthwhile
for an innocent user, unless a very modest index has to be made.
And this completes the circle: different ordering is not wanted, I guess.

\subhead{Enriching the index.}
This use is necessary when for example
\bitem control sequences have to be typeset
\bitem special symbols are needed, or
\bitem cross-references within the index are required.
\smallbreak\noindent
The best way  is to start from the index.elm file.

An example of use is that in
the 4\TeX{} manual the index is sorted on 4TeX,
but in the index a different representation is desired.
(The control sequence
\cs{fourtex} has been used for typesetting instead of 4TeX.)
For that purpose the  file with IRs contains 4TeX and later this
is substituted in the file index.elm by \cs{fourtex}.

Another approach is to supply pairs of control sequences
and sorting keys. See the Looking forward section.

\subhead{Typesetting the enriched file.}
When the default name is used---index.elm---just say \cs{pasteupindex}.
For another file name  assign this name to the toks variable \cs{indexfile},
prior to the invocation of \cs{pasteupindex}.

\head{Tests}
The macros have been tested on the file which was obtained from the
\TeX book chapters 1 to 6. The (slightly adapted) file of raw IRs
and the resulting sorted and compressed index entries have been included in
the Appendices A and B.
The test had to do with some 220 raw IRs.

A driver program, which starts from a file of IRs
not necessarily generated by manmac, is
\beginverbatim
\input blue.fmt
%\irfile{erik.15b}    %file with 6 entries
\irfile{erik.16b}     %file with 19 entries
%\irfile{indexdat.610}%file with 183 entries
%\irfile{erik.cgl}    %file with 228 entries
\sortindex
\pasteupindex
\bye
!endverbatim
Another test file was from the 4\TeX{} manual.
This makeindex file consisted of roughly 760 entries
of the form
|\indexentry{...}{<number>}|.
I first transformed this file---by \TeX{} :-)))---into a file obeying
the IR syntax, via
\beginverbatim
\newwrite\erik
\immediate\openout\erik=erik.cgl
\def\indexentry#1#2{%
 \immediate\write\erik{#1 !!0 #2.}}
!endverbatim
Then I  edited the file in order to
\bitem remove the backslash(es) in the middle of the word part
\bitem adjust IR type for control sequences (0 into 2)
       such that the sorting et cetera went smooth.
\smallbreak
As result I obtained 343 sorted and compressed index entries.
For typesetting some back substitutions had to be made
\bitem in between backslashes inserted again
\bitem the substitution/insertion of special control sequences.
\smallbreak
The total sorting time on my Mac Classic II was roughly 20 minutes,
with 12200  IR comparisons, and 54149 words of memory used.\ftn{A
   dummy job which just stores the IRs
   but does not sort nor reduce the number of entries needed
   34884 words of memory.}
As format I used blue.fmt.\ftn{While proofing  this work,
   it needs less hand work, because the control sequences can be accounted
   for via sort key pairs. See the Looking forward section.}

A final test was about copy with font changes and accents as
part of the IRs. This file has been supplied  in the
second example of this article.

\head{Robustness}
The weak point in this automated complicated process is
the specification of the IRs. When wrong ones are supplied
low-level \TeX{} error messages will emerge, and definitely
will put off a user. My only remedy to this is
\bitem don't hardly use markup within the IR
\bitem don't use active charcters as part of the IR
\bitem don't use \TeX{} special characters, especially
       backslashes apart from a single control sequence (a type 2
       IR.)
\smallbreak\noindent %To locate errors
I also print in the log file the number
of elements to be sorted: n. This must be greater than zero.
When n=0 is printed, the file of raw index entries is apparently empty,
and 9 out of the 10 cases the asynchronous behaviour of the OTR is
the cause, meaning that the file was already closed before
it was written.

When the file is empty, as argument of \cs{filetoarray}, a message is
delivered in the log file.

In the macros I have left some \cs{immediate}\cs{write}s, preceded by
\%, which can be used to follow what is compared. This is handy
when spotting an out of order IR.

\head{Looking backward}
It all started with sorting an array in SiB. In the early
stage of this paper I adhered the model to allow writing IRs
to a file and also, as option, to write directly to the array.
Because of the latter, I had to modify the OTR such that
the array elements were extended with page numbers.
I used the mark mechanism and it worked.\ftn{However there
   was still a detail to be fixed: the first mark was also
   written in the main vertical list.}
I abandonned this option for simplicity reasons. When restricted
to writing to a file a reader does not have to bother about the OTR,
and no redefinitions of the array elements are needed.

A price I had to pay for flexibility is the
generation of  the replacement texts for control sequences to be
ignored, each time in every invocation of \cs{makexref}.

Another `inefficiency' is the `generation' of the ordering table.

Perhaps, I should just have included the `tables' as such instead.

A final point is the general conflict with control sequences
already in use.


\head{Looking forward}
Is it realistic to expect that there will be another user besides me?
I don't think so, because history has it that
manmac as such has been neglected at large,
and I don't see
why people would nevertheless prefer my work,
which is so intimately connected to manmac.

Whatever the future has in store, let us go on.

\subhead{Subsidiary entries.}
What are the requirements for this?
Let us assume that the markup for a subsidiary entry starts with \cs{sub}.
IMHO the following specs are relevant
\bitem \cs{sub} should be neglected in the copy
\bitem write \cs{sub} as string to the file index
\bitem neglect \cs{sub} while sorting
\bitem `reduce' entries which differ in subentries
       by suppressing the main entry except for the first time,
       while typesetting the index element
\bitem indent the subsidiary entry by
       \cs{parindent} while typesetting.
\smallbreak\noindent
The above specs can be realized as follows
\bitem |\let\sub=\relax|
\bitem include \cs{sub} in \cs{conseqs}
\bitem the reduce problem is similar to the typesetting of references,
       where  the author part is printed once for different publications.
       I found that in \AmSTeX, and used it in `BLUe's References.'
\bitem add |\let\sub=\endgraf| in \cs{pasteupreferences}.
\smallbreak\noindent
Actually, the above has been incorporated in blue.fmt.

\subhead{Sorting keys.}
So far we have mostly neglected tokens while sorting.
But, \dots is it do-able to sort each control
sequence according to a sorting key?

This comes down to
\bitem provide a way to specify for
       sorting key pairs, that is pairs of a control sequence
       and its sorting key
\bitem sort on the sorting key
\bitem set the index entries with the embedded
       control sequences according to their definitions.
%\smallbreak

\example{Use of sorting keys}
Suppose that we have
\beginverbatim
\add\fourtex{4tex}to\srtkeypairs
\add\fourtex to\srtkeys
%or
%\setupsrtkeys
Copy with ^{IR \fourtex}
%
\sortindex %with 4tex for \fourtex
\pasteindex%Set `IR \fourtex{} <pagenumbers>'
\bye
!endverbatim
\noindent then the file index will contain the IR
\thisverbatim{\catcode`\!=12 \emc
              \catcode`\;=0 }
\beginverbatim
IR \fourtex{} !0 <pageno>
;endverbatim\noindent
The above will be sorted on 4tex.
The key issue in the implementation is to extend
\cs{nxtwindex} by the test \cs{pophead}$\in$ \cs{srtkeys}.
If the test yields true sort further on  |<sorting key><tail>|,
that is insert the sorting key.

Actually the above has been included in blue.fmt with as defaults
\beginverbatim
\conseqs{\c\space\bf\it\rm\tt\sub\relax}
\consyms{\`\'\"\^\~}
\srtkeypairs{\TeX{tex}
             \LaTeX{latex}
             \AmSTeX{amstex}}
\srtkeys{\TeX\LaTeX\AmSTeX}
!endverbatim\noindent
In order to use this nice feature extend the script as follows
\beginverbatim
\add...to\srtkeypairs%one or more pairs
\setupsrtkeys        %extends the set of
                     %sort keys
...%copy proper
\sortindex
\pasteupindex
!endverbatim\noindent
The last issue of suppressing the main word with multiple sub entries
can be implemented too. For the moment I refrained, and will wait
for user action.

\head{Availability}
The macros are released in the public domain as part of blue.fmt,
version November 1994.

Needed from manmac are the IR macros, |^| and its auxiliaries,
next to some macros for handling the doublecolumns, for example
\cs{balancecolumns}. Some macros from SiB are used too, especially
the sorting macros.
An easy way is to include blue.fmt, which contains them all.

\head{Acknowledgements}
Erik Frambach thank you for the file of 4\TeX, your
assitance, and your sound judgement.
As usual Jos Winnink helped me
again to procruste the markup of the article
into maps.sty.

\head{Conclusion}
The macros work smoothly for
a modest and practical index.
I intend to  use the macros in the near future for my
`Publishing with \TeX' booklet.

The macros serve an educational purpose,
and  stimulate thinking.

My added value to manmac is, that a modest index can be
processed in a one-pass job. More complex indexes
can be processed via a proof run, editing of index.elm,
and a final run with index.elm inserted as copy.

For a foolproof approach it is necessary to
look ahead for general tokens.
The problem is that we can't account for all the
control sequences or active characters to be used.
For indexes of modest complexity my limited
approach is  good enough.
The bonus is simplicity throughout.

In general it is difficult to know when to stop,
as Schumacher in his precious `Small is beautiful'
already pointed out.
My case rest.

\pasteupreferences

\newcol
\head{Appendix A: File of raw IRs from the \TeX book}
\thisverbatim{\catcode`\~=0
   \catcode`\!=12
}
\beginverbatim
%Entries with non-monotone page numbers have
%been added to enforce range representation.
tau !2 1.
epsilon !2 1.
chi !2 2.
chi !2 1.
beauty !0 1.
logo !0 1.
TEX !0 1.
Honeywell Information Systems !0 1.
Bemer, Robert, see TEX, ASCII !0 1.
TeX !1 1.
PLATO !0 2.
BACON !0 2.
quotation marks !0 3.
ASCII !0 3.
apostrophe !0 3.
blank space !0 3.
dashes !0 3.
hyphens !0 3.
minus signs !0 3.
En-dash !0 3.
En-dash !0 2.
Em-dash !0 5.
bibliography !0 4.
ligatures !0 4.
ligatures !0 3.
kerning !0 4.
dangerous bend !0 4.
lq !2 4.
rq !2 4.
quotes within quotes !0 4.
thinspace !2 4.
, !2 4.
SWIFT !0 5.
JEVONS !0 5.
escape character !0 6.
backslash !0 6.
control sequences !0 6.
markup commands, see control sequences !0 6.
input !2 6.
Polya !0 6.
Szego !0 6.
acute !0 6.
umlaut !0 6.
' !0 6.
" !0 6.
accents !0 6.
accents !0 4.
accents !0 5.
control word !0 6.
letter !0 6.
control symbol !0 6.
space !0 6.
* !2 6.
<return> !2 7.
<tab> !2 7.
carriage-return, see <return> !0 7.
logo !0 7.
TeX !2 7.
pi !2 7.
Pi !2 7.
aleph !2 7.
infty !2 7.
le !2 7.
ge !2 7.
ne !2 7.
oplus !2 7.
otimes !2 7.
uppercase !0 7.
lowercase !0 7.
primitive !0 7.
input !2 7.
' !2 7.
" !2 7.
accent !2 7.
exercise !2 8.
show !2 8.
thinspace !2 8.
kern !2 8.
log file !0 8.
SELDEN !0 9.
LINCOLN !0 9.
typeface !0 10.
bold !0 10.
fonts !0 10.
rm !2 10.
sl !2 10.
it !2 10.
tt !2 10.
bf !2 10.
typewriter type !0 10.
face !0 10.
roman type !0 10.
oblique !0 10.
Slanted type !0 10.
italic type !0 10.
curly brace !0 10.
brace !0 10.
grouping !0 10.
Dieter !0 10.
/ !2 10.
El\`eve !0 10.
punctuation !0 11.
nullfont !2 11.
points !0 11.
dangerous bend !0 11.
subscripts !0 11.
tenrm !2 11.
ninerm !2 11.
tensl !2 11.
ninesl !2 11.
baseline !0 11.
tenpoint !2 11.
ninepoint !2 11.
Computer Modern !0 12.
cm fonts !0 12.
font !2 12.
design size !0 12.
at !1 12.
magnification !0 12.
reduction !0 12.
cmr5 !1 12.
piano !0 12.
magstep !2 12.
magstephalf !2 12.
magnification !2 12.
LEE !0 13.
SHAKESPEARE !0 13.
grouping characters !0 14.
curly braces, see braces !0 14.
block structure !0 14.
local !0 14.
TeX !2 14.
space !0 14.
empty group !0 14.
lbrace rbrace !0 14.
ligature !0 14.
control space !0 14.
centerline !2 14.
nested !0 14.
global !2 15.
page number !0 15.
Output routines !0 15.
advance !2 15.
begingroup !2 15.
endgroup !2 15.
nested groups !0 15.
MUIRHEAD !0 16.
HOWARD !0 16.
Running the program !0 17.
** !1 17.
relax !2 17.
return !3 17.
asterisk !0 17.
end !2 17.
[1] !1 17.
texput !1 17.
dvi !1 17.
device independent !0 17.
story\period{}tex !1 17.
hrule !2 17.
vskip !2 17.
eject !2 17.
rule !0 18.
paragraphs !0 18.
blank line !0 18.
empty line !0 18.
umlaut !0 18.
cedilla !0 18.
ties !0 18.
tilde !0 18.
vfill !2 18.
eject !2 18.
file names !0 18.
** !1 18.
* !1 18.
input !2 18.
ampersand !0 18.
format file !0 18.
preloaded formats !0 18.
end !2 19.
percent !0 19.
comments !0 19.
hsize !2 19.
input !2 19.
overfull box !0 19.
[] !1 20.
r\'esum\'e{} !0 253.
leading, see vskip !0 17.
centerline !2 17.
Thor !0 17.
" !2 17.
c !2 17.
Drofnats !0 17.
vfill !2 17.
transcript !0 20.
log file !0 20.
hyphenation !0 20.
discretionary hyphens !0 20.
badness !0 20.
tolerance !2 21.
hbadness !2 21.
underfull box !0 21.
column width !0 21.
measure, see hsize !0 21.
raggedright !2 21.
breaking a paragraph !0 21.
hfuzz !2 21.
dash !2 21.
error messages !0 21.
? !1 22.
italic correction !0 10.
inserting text online !0 22.
online interaction, see interaction !0 22.
interacting with TeX !0 22.
deleting tokens !0 22.
help messages !0 23.
scrollmode !2 23.
nonstopmode !2 23.
batchmode !2 23.
errorstopmode !2 23.
interrupt !0 23.
argument !0 23.
centerline !2 23.
editing !0 24.
errorcontextlines !2 24.
ARISTOTLE !0 25.
HABAKKUK !0 25.
COWPER !0 25.
~endverbatim
\newcol

\head{Appendix B: Index}
The index below has been typeset via
\thisverbatim{\catcode`\!=12
    \catcode`\~=0 }
\beginverbatim
{\obeylines\gdef\typindentry#1
 {%#1 an IR as such
 \if!#1!\expandafter\egroup\else%
 \splitintoks#1%
 \ifcase\digit{\the\indword}\or%
         {\tt\the\indword}\or%
  {\tt\char92\hbox{\the\indword}}\or%
  $\langle\hbox{\the\indword}\rangle$\fi{} %
  \pagenrs.\fi\par}
}
\bgroup\def\par{\endgraf \typindentry}
\obeylines
' !0{} 6.
' !2{} 7.
...

~endverbatim
\subhead{Index.}
{\obeylines\gdef\typindentry#1
 {%#1 a IR
 \if!#1!\expandafter\egroup\else%
 \splitintoks#1%
 \ifcase\digit\the\indword\or%
         {\tt\the\indword}\or%
  {\tt\char92\the\indword}\or%
  $\langle\hbox{\the\indword}\rangle$\fi{} %
  \pagenrs.\fi\par}
}
\bgroup\def\par{\endgraf \typindentry}
\obeylines
' !0{} 6.
' !2{} 7.
" !0{} 6.
" !2{} 7, 17.
* !1{} 18.
* !2{} 6.
** !1{} 17, 18.
, !2{} 4.
[] !1{} 20.
[1] !1{} 17.
/ !2{} 10.
? !1{} 22.
accent !2{} 7.
accents !0{} 4--6.
acute !0{} 6.
advance !2{} 15.
aleph !2{} 7.
ampersand !0{} 18.
apostrophe !0{} 3.
argument !0{} 23.
ARISTOTLE !0{} 25.
ASCII !0{} 3.
asterisk !0{} 17.
at !1{} 12.
backslash !0{} 6.
BACON !0{} 2.
badness !0{} 20.
baseline !0{} 11.
batchmode !2{} 23.
beauty !0{} 1.
begingroup !2{} 15.
Bemer, Robert, see TEX, ASCII !0{} 1.
bf !2{} 10.
bibliography !0{} 4.
blank line !0{} 18.
blank space !0{} 3.
block structure !0{} 14.
bold !0{} 10.
brace !0{} 10.
breaking a paragraph !0{} 21.
c !2{} 17.
carriage-return, see $\langle$return$\rangle$ !0{} 7.
cedilla !0{} 18.
centerline !2{} 14, 17, 23.
chi !2{} 1, 2.
cm fonts !0{} 12.
cmr5 !1{} 12.
column width !0{} 21.
comments !0{} 19.
Computer Modern !0{} 12.
control sequences !0{} 6.
control space !0{} 14.
control symbol !0{} 6.
control word !0{} 6.
COWPER !0{} 25.
curly brace !0{} 10.
curly braces, see braces !0{} 14.
dangerous bend !0{} 4, 11.
dash !2{} 21.
dashes !0{} 3.
deleting tokens !0{} 22.
design size !0{} 12.
device independent !0{} 17.
Dieter !0{} 10.
discretionary hyphens !0{} 20.
Drofnats !0{} 17.
dvi !1{} 17.
editing !0{} 24.
eject !2{} 17, 18.
El{\accent 18 e}ve !0{} 1.
Em-dash !0{} 5.
empty group !0{} 14.
empty line !0{} 18.
En-dash !0{} 2, 3.
end !2{} 17, 19.
endgroup !2{} 15.
epsilon !2{} 1.
errorcontextlines !2{} 24.
error messages !0{} 21.
errorstopmode !2{} 23.
escape character !0{} 6.
exercise !2{} 8.
face !0{} 10.
file names !0{} 18.
font !2{} 12.
fonts !0{} 10.
format file !0{} 18.
ge !2{} 7.
global !2{} 15.
grouping !0{} 10.
grouping characters !0{} 14.
HABAKKUK !0{} 25.
hbadness !2{} 21.
help messages !0{} 23.
hfuzz !2{} 21.
Honeywell Information Systems !0{} 1.
HOWARD !0{} 16.
hrule !2{} 17.
hsize !2{} 19.
hyphenation !0{} 20.
hyphens !0{} 3.
infty !2{} 7.
input !2{} 6, 7, 18, 19.
inserting text online !0{} 22.
interacting with TeX !0{} 22.
interrupt !0{} 23.
it !2{} 10.
italic correction !0{} 10.
italic type !0{} 10.
JEVONS !0{} 5.
kern !2{} 8.
kerning !0{} 4.
lbrace rbrace !0{} 14.
le !2{} 7.
leading, see vskip !0{} 17.
LEE !0{} 13.
letter !0{} 6.
ligature !0{} 14.
ligatures !0{} 3, 4.
LINCOLN !0{} 9.
local !0{} 14.
log file !0{} 8, 20.
logo !0{} 1, 7.
lowercase !0{} 7.
lq !2{} 4.
magnification !0{} 12.
magnification !2{} 12.
magstep !2{} 12.
magstephalf !2{} 12.
markup commands, see control sequences !0{} 6.
measure, see hsize !0{} 21.
minus signs !0{} 3.
MUIRHEAD !0{} 16.
ne !2{} 7.
nested !0{} 14.
nested groups !0{} 15.
ninepoint !2{} 11.
ninerm !2{} 11.
ninesl !2{} 11.
nonstopmode !2{} 23.
nullfont !2{} 11.
oblique !0{} 10.
online interaction, see interaction !0{} 22.
oplus !2{} 7.
otimes !2{} 7.
Output routines !0{} 15.
overfull box !0{} 19.
page number !0{} 15.
paragraphs !0{} 18.
percent !0{} 19.
Pi !2{} 7.
pi !2{} 7.
piano !0{} 12.
PLATO !0{} 2.
points !0{} 11.
Polya !0{} 6.
preloaded formats !0{} 18.
primitive !0{} 7.
punctuation !0{} 11.
quotation marks !0{} 3.
quotes within quotes !0{} 4.
raggedright !2{} 21.
reduction !0{} 12.
relax !2{} 17.
r{\accent 19 e}sum{\accent 19 e}{} !0{} 253.
return !3{} 17.
\<return> !2{} 7.
rm !2{} 10.
roman type !0{} 10.
rq !2{} 4.
rule !0{} 18.
Running the program !0{} 17.
scrollmode !2{} 23.
SELDEN !0{} 9.
SHAKESPEARE !0{} 13.
show !2{} 8.
sl !2{} 10.
Slanted type !0{} 10.
space !0{} 6, 14.
story.{}tex !1{} 17.
subscripts !0{} 11.
SWIFT !0{} 5.
Szego !0{} 6.
<tab> !2{} 7.
tau !2{} 1.
tenpoint !2{} 11.
tenrm !2{} 11.
tensl !2{} 11.
TEX !0{} 1.
TeX !1{} 1.
TeX !2{} 7, 14.
texput !1{} 17.
thinspace !2{} 4, 8.
Thor !0{} 17.
ties !0{} 18.
tilde !0{} 18.
tolerance !2{} 21.
transcript !0{} 20.
tt !2{} 10.
typeface !0{} 10.
typewriter type !0{} 10.
umlaut !0{} 6, 18.
underfull box !0{} 21.
uppercase !0{} 7.
vfill !2{} 17, 18.
vskip !2{} 17.

\newcol
\head{Appendix C: The index macros}
Macros from blue.fmt (and manmac) are needed.
Those have not been included.
\thisverbatim{\numvrb
              \catcode`\<=12
              \catcode`\!=12
              \catcode`\|=12
              \catcode`\;=0
}
\beginverbatim
%From BLUe's Index                Oct 94%;numvrb
%Some unused macros are left in.
\newread\inxin
\newtoks\indword
\newtoks\indexfile
   %To parameterize the resulting index
\newtoks\irfile
   %To parameterize the IRs
\newtoks\indexname
\newtoks\preindex
\newtoks\postindex
\newtoks\conseqs
\newtoks\consyms
\newtoks\srtkeys
\newtoks\srtkeypairs
\newtoks\ignores
%Initializations
\proofmodetrue
\irfile{index}
\indexfile{index.elm}
\indexname{Index}
\preindex{\head{\the\indexname}}
\postindex{}
\immediate\openout\inx=index
\conseqs{\c\space\bf\it\rm\tt
   \sub\relax}
\consyms{\`\'\"\^\~}
\srtkeypairs{\TeX{tex}
             \LaTeX{latex}
             \AmSTeX{amstex}}
\srtkeys{\TeX\LaTeX\AmSTeX}
\let\sub\relax
%Macros
%
%User level
%;vrblin=100
\def\sortindex{%Nov 1994, cgl
%Purpose:
%To sort IR file.
%Input: default index is sorted
%      ( file specified in \irfile)
%Output: file index.elm.
   \newpage\immediate\closeout\inx
   \filetoarray{\the\irfile}
   \immediate\write16{Sorting n=\the\n.
      Please wait, O(nlog n) process.}
   \let\cmp\cmpir\let\nxtw\nxtwindex
   \otindex\let\ \space
   {%Make sortkey defs
    \ea\sokdef\the\skpairs\fedkos\relax
   \sort
   {\let\spaceseparator\space
   \setupnxtokens\def\ {\nx\ }%
   \immediate\write16{Range reduction.}
   \redrngtofile{index.srt}
   \immediate\write16{After reduction and
    writing to file index.srt; n=\the\n.}
   \immediate\write16{Transform
         index.srt-->index.elm.}
   \tawfiletofile{index.srt}{\the
                  \indexfile}}}
%
%Set up set of \srtkeys
\def\setupsrtkeys{\ea
 \sok\the\srtkeypairs\kos\relax}
%;vrblin=150
\def\pasteupindex{%Nov 1994, cgl
%Purpose:
%To set index in (balanced) doublecolumn.
%The index is preceded by contents of
%\preindex and followed by contents of
%\postindex.
%Input: default index.elm is set
%       (file specified in \indexfile).
%Biased by manmac's \begindoublecolumns
 \newpage \begingroup
 \def\space{{\tt\char32 }}%
 \the\preindex\par
 \pageheight\vsize
 \pagewidth\pagewd%anachronism
 \parindent1em
 \output={\global\setbox\partialpage=
  \vbox{\unvbox255\bigskip}}%
 \eject
 \output={\bluedoublecolumnout}%
 \hsize=8.5cm \vsize=51cm%blue.fmt values
 \parskip0pt plus.8pt\relax
 \obeylines\everypar{%
    \hangindent2\parindent}%
 \let\par\endgraf
 \let\sub\endgraf
%
 \input\the\indexfile\relax
%
%endpasteupindex part biased by
%manmac's \enddoublecolumns
 \output={\balancecolumns}\eject
 \endgroup
 \pagegoal=\vsize\the\postindex}
%
%Add an element #1 to toks var #2
\def\add#1to#2{#2\ea{\the#2#1}}
%
%Inner level
%
%IR creation
%;vrblin=200
\def\makexref{\ifproofmode%Mod cgl oct 94
 \bgroup\def\ {\string\ }%
 \def\process##1{\def##1{\string##1 }}%
  \ea\ea\ea\fifo\ea\the\ea\conseqs
                \the\srtkeys\ofif
 \def\process##1{\def##1{\string##1}}%
 \ea\fifo\the\consyms\ofif
 \xdef\writeit{\write\inx{\text{}
    !\xreftype\spaceseparator
    \nx\number\pageno.}}\writeit
 \egroup
 \else\ifhmode\kern0pt\fi\fi
 \ifsilent\ignorespaces\else{\next}\fi
}
%
%Sorting
%;vrblin=250
\def\cmpir#1#2{%#1, #2 defs
%Result: \status= 0, 1, 2 if
%        \val{#1} =, >, < \val{#2}
%\immediate\write16{Compared are: *#1*
%                   and *#2*}%
\ea\ea\ea\decom\ea#1#2}
%
\def\nxtwindex#1#2{%
%Function:
%On input: #1 contains the `word'
%As result: #2 contains the value
%   of the first non-ignored token as given
%   in the ordering table.
%#1 contains the rest of the `word'
 \def\pop##1##2\pop{%
 \gdef#1{##2}\def\pophead{##1}}%head and tail
 \ea\pop#1\pop%split in head and tail
 \ignores\ea\ea\ea{\ea
  \the\ea\conseqs\the\consyms}%
 \ea\loc\pophead{\the\ignores}%
 \iffound\ifx\empty#1 \chardef#2=0
         \else\nxtwindex#1#2 \fi
 \else
 \ea\loc\pophead{\the\srtkeys}%
  \iffound\xdef\pophead{\pophead}%
    \ea\ea\ea\gdef\ea\ea\ea#1\ea\ea\ea
      {\ea\pophead#1}%
    \nxtwindex#1#2
  \else
  \ea\let\ea#2\csname ot\pophead\endcsname
  \fi
 \fi}
%
\def\otindex{%Parameters: Ordering `table'
%Special cases
\ea\chardef\csname ot \endcsname=0
\ea\chardef\csname ot\space\endcsname=0
%{|}~(\char126) in ASCII after lowercase
%^ active character
%Bulk according to ACII
\def\process##1{\ea\chardef
   \csname ot##1\endcsname=`##1 }
%lowercase letters
\fifo abcdefghijklmnopqrstuvwxyz\ofif
\chardef\otij=`y \chardef\otIJ=`y
%other characters
\fifo !"##$&'()*+,-./0123456789:;<=>?@
      []_`\ofif
%uppercase letters equal lowercase
\def\process##1{\ea\chardef
  \csname ot##1\endcsname=\lccode`##1 }
\uppercase{\fifo
  abcdefghijklmnopqrstuvwxyz\ofif}
}
%
%Range reduction
%;vrblin=400
\def\redrngtofile#1{%Reduction of \1,...,\n,
%with range representation of page numbers
\immediate\openout\inx=#1
 {\k1\kk0 \ifnum\n>0
 \ea\ea\ea\splitwn\csname\the\k\endcsname
 \let\refer\word
 \let\nrsrng\empty\prcrng\num\fi
 \loop\ifnum\k<\n\advance\k1
  \ea\ea\ea\splitwn\csname\the\k\endcsname
  \ifx\refer\word%extend \nrsrng with number
    \prcrng\num
  \else%write record to \kk
   \advance\kk1 \strnrs
   \immediate\write\inx{\refer\spaceseparator
      \nrsrng.}%
   \let\nrsrng\empty\init\num
   \prcrng\num\let\refer\word
  \fi
 \repeat\ifnum1<\n
  \advance\kk1 \strnrs
  \immediate\write\inx{\refer\spaceseparator
    \nrsrng.}%
 \global\n\kk\fi
 }\immediate\closeout\inx}
%
%Copying
%;vrblin=500
\def\filetoarray#1{%#1 is file name
 \immediate\openin\inxin=#1\relax
 \ifeof\inxin\immediate\write16{File #1 empty
   or non-existent.}%
 \fi \n\kzero\continuetrue
 \loop\ifeof\inxin\continuefalse\fi
 \ifcontinue\advance\n1 \immediate
 \read\inxin t\ea o\csname\the\n\endcsname
%\immediate\write16{k: \number\n:
%     \csname\the\n\endcsname}%
 \repeat\advance\n-1
 \immediate\closein\inxin}
%
\def\tawfiletofile#1#2{\continuetrue
 \immediate\openin\inxin=#1\relax
 \immediate\openout\inx=#2\relax
 \loop\read\inxin to\IR
   \ifeof\inxin\continuefalse\fi
 \ifcontinue\trfandwrite\IR
 \repeat
 \immediate\closein\inxin
 \immediate\closeout\inx
}
%
\def\setupnxtokens{%
 \def\process##1{\def##1{\nx##1}}%
  \ea\ea\ea\fifo\ea\the\ea\conseqs
                \the\srtkeys\ofif
 \def\process##1{\def##1{\string##1}}%
 \ea\fifo\the\consyms\ofif
}
%
\def\trfandwrite#1{\ea\splitintoks#1%
 \immediate\write\inx{\nx\noindent
  \ifcase\digit{\the\indword}\or
   {\nx\tt\the\indword}\or
   {\nx\tt\char92\hbox{\the\indword}}\or
   $\nx\langle\hbox{\the\indword}\nx\rangle
    $\fi\spaceseparator\pagenrs.}}
%
\def\splitintoks#1 !#2 #3.{\indword{#1}%
  \chardef\digit=#2\relax\def\pagenrs{#3}}
%
%Typesetting;vrblin=600
\def\bluedoublecolumnout{%
%Biased by manmac's doublecolumnout
 \splittopskip=\topskip
 \splitmaxdepth=\maxdepth \dimen@=25cm
 \advance\dimen@ by-\ht\partialpage
 \setbox0=\vsplit255 to\dimen@
 \setbox2=\vsplit255 to\dimen@
 \blueonepageout\pagesofar
 \unvbox255 \penalty\outputpenalty}
%
\def\blueonepageout#1{%
%Biased by manmac's \onepageout
 \shipout\vbox{%
 \vbox to\baselineskip{\null
         \the\headline\vss}%
 \kern2ex
 \vbox to \pageheight{#1}%
 \kern1ex
 \the\footline
 }\advancepageno}
%Auxiliaries
%SetOfKeys;vrblin=700
\def\sok#1#2{%Function:
%Build from \srtkeypairs \srtkeys
%via \ea\sok\srtkeypairs\kos\relax
\ifx#1\kos\kos\fi
  \srtkeys\ea{\the\srtkeys#1}\sok}
\def\kos#1\sok{\fi}
%
\def\sokdef#1#2{%Function:
%Build from \skpairs srtkey defs
\ifx#1\fedkos\fedkos\fi
  \def#1{#2}\sokdef}
\def\fedkos#1\sokdef{\fi}
%;nonum
%Table of contents: blue.ind
%Variables
%   \indexname................8, 19
%   \preindex.................9, 20
%   \postindex................10, 21
%   \indword..................3
%   \indexfile................4, 19
%   \irfile...................6, 18
%   \conseqs..................11, 24-25
%   \consyms..................12, 26
%   \srtkeys..................13, 30
%   \srtkeypairs..............14, 28-29
%   \ignores..................15
%User level macros
%   \sortindex................101-125
%   \pasteupindex.............151-183
%   \add#1to#2................186
%   \setupsrtkeys.............127-129
%Lower level macros
%IR Creation
%   \makexref.................201-214
%Sorting
%   \cmpir....................251-256
%   \nxtwindex................258-282
%   \otindex..................284-304
%Range reduction
%   \redrngtofile.............401-424
%Copying
%   \filetoarray..............501-512
%   \tawfiletofile............514-523
%   \trfandwrite..............533-539
%   \steupnxtokens............525-531
%   \splitintoks..............541-542
%OTR doublecolumns
%   \bluedoublecolumnout......601-609
%   \blueonepageout...........611-620
%Auxiliaries
%   \sok......................701-705
%   \sokdef...................706-711
%History of changes
%Nov    1994 Set up.
%end%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%index%
;endverbatim
\endscript
